﻿using Sinacor.Infra.Common.Exceptions;
using System;
using Sinacor.Infra.UI.FileTransfer.Client;
using PSE.ProcessManager.Common.Process;
using Sinacor.Infra.UI.Common;
using Sinacor.Infra.UI.Authorization;
using Sinacor.UI.Bovespa.ManutencaoOrdens.Model;

namespace Sinacor.UI.Bovespa.ManutencaoOrdens.Presenter
{
    /// <summary>
    /// CasamentoAutomatico
    /// </summary>
    public class CasamentoAutomatico : BasePresenter<ICasamentoAutomatico>
    {
        #region Campos
        #region Atributos
        private bool _erroProcesso = false;
        #endregion Atributos

        #region ModelCollection
        private ModelCollection<Model.Calendario> _calendario;        
        #endregion ModelCollection

        #region Communication
        private Communication.Calendario _communicationCalendario;
        private Communication.CasamentoAutomatico _communicationCasamentoAutomatico;
        private Communication.CasamentoAutomaticoPreBoleto _communicationCasamentoAutomaticoPreBoleto;

        private Communication.RecasamentoAutomatico _communicationRecasamentoAutomatico;
        private Communication.ControleMovimentoOrdens _communicationControleMovimentoOrdens;
        #endregion Communication

        #region Model
        private Model.DadosCasamentoAut _dadosExecucao;
        private Model.InformacoesMovimento _informacoesMovimento;
        #endregion Model

        #endregion Campos

        #region Construtor
        /// <summary>
        /// Construtor padrão
        /// </summary>
        public CasamentoAutomatico(ICasamentoAutomatico view)
            : base(view)
        {
            #region Communication
            _communicationCasamentoAutomatico = new Communication.CasamentoAutomatico(this.Session);
            _communicationCasamentoAutomaticoPreBoleto = new Communication.CasamentoAutomaticoPreBoleto(this.Session);
            _communicationRecasamentoAutomatico = new Communication.RecasamentoAutomatico(this.Session);

            _communicationCalendario = new Communication.Calendario(this.Session);
            _communicationControleMovimentoOrdens = new Communication.ControleMovimentoOrdens(this.Session);
            #endregion Communication

            #region CommunicationError
            _communicationCasamentoAutomatico.CommunicationError += new EventHandler<Sinacor.Infra.Common.CommunicationErrorEventArgs>(_communicationCasamentoAutomatico_CommunicationError);
            _communicationCasamentoAutomaticoPreBoleto.CommunicationError += new EventHandler<Sinacor.Infra.Common.CommunicationErrorEventArgs>(_communicationCasamentoAutomaticoPreBoleto_CommunicationError);
            _communicationRecasamentoAutomatico.CommunicationError += new EventHandler<Sinacor.Infra.Common.CommunicationErrorEventArgs>(_communicationRecasamentoAutomatico_CommunicationError);
            #endregion CommunicationError

            #region Finalized
            _communicationCasamentoAutomatico.Finalized += new EventHandler(_communicationCasamentoAutomatico_Finalized);
            _communicationCasamentoAutomaticoPreBoleto.Finalized += new EventHandler(_communicationCasamentoAutomaticoPreBoleto_Finalized);
            _communicationRecasamentoAutomatico.Finalized += new EventHandler(_communicationRecasamentoAutomatico_Finalized);
            #endregion Finalized
            
            #region Model
            _informacoesMovimento = new Model.InformacoesMovimento();
            _dadosExecucao = new Model.DadosCasamentoAut();
            #endregion Model
        }

        
        #endregion Construtor

        #region Eventos
        #region _communicationCasamentoAutomatico_Finalized
        /// <summary>
        /// _communicationCasamentoAutomatico_Finalized
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">EventArgs</param>
        public void _communicationCasamentoAutomatico_Finalized(object sender, EventArgs e)
        {
            if (!_erroProcesso)
            {                
                View.InformarOperacaoSucesso();
            }
            View.HabilitarControles();
        }
        #endregion _communicationCasamentoAutomatico_Finalized
        #region _communicationCasamentoAutomaticoPreBoleto_Finalized
        /// <summary>
        /// _communicationCasamentoAutomaticoPreBoleto_Finalized
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">EventArgs</param>
        public void _communicationCasamentoAutomaticoPreBoleto_Finalized(object sender, EventArgs e)
        {
            if (!_erroProcesso)
            {                
                View.InformarOperacaoSucesso();
            }
            View.HabilitarControles();
        }
        #endregion _communicationCasamentoAutomaticoPreBoleto_Finalized
        #region _communicationRecasamentoAutomatico_Finalized
        /// <summary>
        /// _communicationRecasamentoAutomatico_Finalized
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">EventArgs</param>
        public void _communicationRecasamentoAutomatico_Finalized(object sender, EventArgs e)
        {
            if (!_erroProcesso)
            {                
                View.InformarOperacaoSucesso();
            }
            View.HabilitarControles();
        }
        #endregion _communicationRecasamentoAutomatico_Finalized 

        #region _communicationCasamentoAutomatico_CommunicationError
        /// <summary>
        /// _communicationCasamentoAutomatico_CommunicationError
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">Sinacor.Infra.Common.CommunicationErrorEventArgs</param>
        void _communicationCasamentoAutomatico_CommunicationError(object sender, Sinacor.Infra.Common.CommunicationErrorEventArgs e)
        {            
            _erroProcesso = true;
            
            if (e.Exception is BusinessException ||
                e.Exception is ValidationException)
                base.HandleException(e.Exception);
            else                
                View.InformarErroProcessoCasamentoAutomatico();
        }
        #endregion _communicationCasamentoAutomatico_CommunicationError
        #region _communicationCasamentoAutomaticoPreBoleto_CommunicationError
        /// <summary>
        /// _communicationCasamentoAutomaticoPreBoleto_CommunicationError
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">Sinacor.Infra.Common.CommunicationErrorEventArgs</param>
        void _communicationCasamentoAutomaticoPreBoleto_CommunicationError(object sender, Sinacor.Infra.Common.CommunicationErrorEventArgs e)
        {
            _erroProcesso = true;            
            if (e.Exception is BusinessException ||
                e.Exception is ValidationException)
                base.HandleException(e.Exception);
            else
                View.InformarErroProcessoCasamentoAutomaticoPreBoleto();
        }
        #endregion _communicationCasamentoAutomaticoPreBoleto_CommunicationError
        #region _communicationRecasamentoAutomatico_CommunicationError
        /// <summary>
        /// _communicationRecasamentoAutomatico_CommunicationError
        /// </summary>
        /// <param name="sender">object</param>
        /// <param name="e">Sinacor.Infra.Common.CommunicationErrorEventArgs</param>
        void _communicationRecasamentoAutomatico_CommunicationError(object sender, Sinacor.Infra.Common.CommunicationErrorEventArgs e)
        {
            _erroProcesso = true;            
            if (e.Exception is BusinessException ||
                e.Exception is ValidationException)
                base.HandleException(e.Exception);
            else
                View.InformarErroProcessoRecasamentoAutomatico();
        }
        #endregion _communicationRecasamentoAutomatico_CommunicationError

        #endregion Eventos

        #region ModelCollection
        /// <summary>
        /// Binding com o combobox
        /// </summary>
        public ModelCollection<Model.Calendario> Calendario
        {
            get
            {
                return _calendario;
            }
            set
            {
                _calendario = value;
            }
        }
        #endregion ModelCollection

        #region Model
        public Model.DadosCasamentoAut DadosExecucao
        {
            get
            {
                return _dadosExecucao;
            }
            set
            {
                _dadosExecucao = value;
            }
        }

        public Model.InformacoesMovimento InformacoesMovimento
        {
            get
            {
                return _informacoesMovimento;
            }
            set
            {
                _informacoesMovimento = value;
            }
        }
        
        #endregion Model

        #region Métodos Públicos
       
        #region ExecutarCasamentoAutomatico
        /// <summary>
        /// ExecutarCasamentoAutomatico
        /// </summary>
        public void ExecutarCasamentoAutomatico()
        {
            try
            {
                if (View.ConfirmarCasamentoAut())
                {
                    _erroProcesso = false;
                    _communicationCasamentoAutomatico.Execute(DadosExecucao);
                    View.DesabilitarControles();
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }
        #endregion ExecutarCasamentoAutomatico
        #region ExecutarCasamentoAutomaticoPreBoleto
        /// <summary>
        /// ExecutarCasamentoAutomaticoPreBoleto
        /// </summary>
        public void ExecutarCasamentoAutomaticoPreBoleto()
        {
            try
            {
                if (View.ConfirmarCasamentoAutPreBoleto())
                {
                    _erroProcesso = false;
                    _communicationCasamentoAutomaticoPreBoleto.Execute();
                    View.DesabilitarControles();
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }
        #endregion ExecutarCasamentoAutomaticoPreBoleto
        #region ExecutarRecasamentoAutomatico
        /// <summary>
        /// ExecutarRecasamentoAutomatico
        /// </summary>
        public void ExecutarRecasamentoAutomatico()
        {
            try
            {
                if (View.ConfirmarRecasamentoAut())
                {
                    _erroProcesso = false;
                    _communicationRecasamentoAutomatico.Execute(DadosExecucao);
                    View.DesabilitarControles();
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
        }
        #endregion ExecutarRecasamentoAutomatico

        #region Inicializar
        /// <summary>
        /// Inicializar
        /// </summary>
        public void Inicializar()
        {
            try
            {
                _informacoesMovimento = ObterInformacoesMovimento();

                Calendario = ConsultarCalendario();
                View.AtualizarCalendario();

                if (!VerificarProcessos())
                {
                    VerificarPermissoes();                    

                    //Recuperar informações da última execução de cada processo
                    //*********************************************************
                    //Funcionalidade ainda não disponibilizada pela Infra.
                    //Não implementar esta ação.
                    //*********************************************************            }
                    //Verificar o diagrama de sequência
                    //ViewSmartClient.Inicializar()
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            } 
        }
        #endregion Inicializar
        #region ObterInformacoesMovimento
        /// <summary>
        /// ObterInformacoesMovimento
        /// </summary>
        /// <returns>Model.InformacoesMovimento</returns>
        private Model.InformacoesMovimento ObterInformacoesMovimento()
        {
            Model.InformacoesMovimento _retorno = new InformacoesMovimento();
            try
            {
                _retorno = _communicationControleMovimentoOrdens.ObterInformacoesMovimento(new DataMovimento());
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
            return _retorno;
        }
        #endregion ObterInformacoesMovimento

        #region VerificarPermissoes
        /// <summary>
        /// Configurar as opções de casamento de acordo com as funções de permissão de
        /// execução
        /// </summary>
        private void VerificarPermissoes()
        {
            try
            {
                if (!AuthorizationManager.GetInstance().CheckUserAccess("ORD", "CAPR"))
                {
                    View.DesabilitarCasamentoAutPreBoleto();
                    return;
                }
                if (!AuthorizationManager.GetInstance().CheckUserAccess("ORD", "CAUT"))
                {
                    View.DesabilitarCasamentoAut();                
                    return;
                }
                if (!AuthorizationManager.GetInstance().CheckUserAccess("ORD", "RAUT"))
                {
                    View.DesabilitarRecasamentoAut();                
                    return;
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            } 
        }
        #endregion VerificarPermissoes
        #region VerificarProcessos
        /// <summary>
        /// Verifica se algum dos processos de casamento está sendo executado, caso esteja
        /// irá desabilitar a possibilidade de execução de qualquer processo de casamento
        /// </summary>
        private bool VerificarProcessos()
        {
            bool _retorno = false;
            try
            {
                if (_communicationCasamentoAutomaticoPreBoleto.IsProcessRunning())
                {
                    View.DesabilitarControles();
                    View.InformarProcessamentoCasamentoAutPreBoleto();
                    _retorno = true;
                }
                if (_communicationCasamentoAutomatico.IsProcessRunning())
                {
                    View.DesabilitarControles();
                    View.InformarProcessamentoCasamentoAut();
                    _retorno = true;
                }
                if (_communicationRecasamentoAutomatico.IsProcessRunning())
                {
                    View.DesabilitarControles();
                    View.InformarProcessamentoRecasamentoAut();
                    _retorno = true;
                }
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            } 
            return _retorno;
        }
        #endregion VerificarProcessos

        #endregion Métodos Públicos

        #region Métodos Privados
        #region ConsultarCalendario
        /// <summary>
        /// Consulta o calendário de pregões
        /// </summary>
        /// <returns><!--ModelCollection<Model.Calendario>--></returns>
        private ModelCollection<Model.Calendario> ConsultarCalendario()
        {
            ModelCollection<Model.Calendario> _retorno = null;
            try
            {
                _retorno = _communicationCalendario.ConsultarCalendario();
            }
            catch (Exception ex)
            {
                base.HandleException(ex);
            }
            return _retorno;
        }
        #endregion ConsultarCalendario

        #endregion Métodos Privados

        public override void Dispose()
        {
            _communicationCasamentoAutomatico.Disconnect();
            _communicationCasamentoAutomaticoPreBoleto.Disconnect();
            _communicationRecasamentoAutomatico.Disconnect();

            base.Dispose();
        }
    }
}
